﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Collections;

namespace Century.EnterpriseLibrary.Caching
{
    public class CacheableList<T> : List<T>
    {
        public delegate void CacheableListActionHandler(CacheableList<T> list, T item, bool changeOnDb);

        public event CacheableListActionHandler OnAdd;
        public event CacheableListActionHandler OnRemove;
        public event CacheableListActionHandler OnUpdate;

        /// <summary>
        /// Method to add an item in Cacheable List
        /// <para>Warning!!</para>
        /// <para>This Method Add Item in database as well.</para>
        /// </summary>
        /// <param name="item">Item to add</param>
        new public void Add(T item)
        {
            Add(item, true);
        }

        /// <summary>
        /// Method to add an item in Cacheable List
        /// </summary>
        /// <param name="item">Item to add</param>
        /// <param name="changeOnDb">true if you want to add it to Database</param>
        public void Add(T item, bool changeOnDb)
        {
            if (null != OnAdd)
            {
                OnAdd(this, item, changeOnDb);
            }
            base.Add(item);
        }

        /// <summary>
        /// Method to remove an item from Cacheable List
        /// <para>Warning!!</para>
        /// <para>This Method Remove Item from database as well.</para>
        /// </summary>
        /// <param name="item">Item to remove</param>
        /// <param name="changeOnDb">true if you want to remove it from Database</param>
        /// <returns></returns>
        new public bool Remove(T item)
        {
            return Remove(item, true);
        }

        /// <summary>
        /// Method to remove an item from Cacheable List
        /// </summary>
        /// <param name="item">Item to remove</param>
        /// <param name="changeOnDb">true if you want to remove it from Database</param>
        /// <returns></returns>
        public bool Remove(T item, bool changeOnDb)
        {
            if (null != OnRemove)
            {
                OnRemove(this, item, changeOnDb);
            }
            return base.Remove(item);
        }

        /// <summary>
        /// Method to update an item in Cacheable List
        /// <para>Warning!!</para>
        /// <para>This Method Update Item in database as well.</para>
        /// </summary>
        /// <param name="predicate">Predicate To Find Item To Update</param>
        /// <param name="newValue">New Value Of Item To Update</param>
        public void Update(Func<T, bool> predicate, T newValue)
        {
            Update(predicate, newValue, true);
        }

        /// <summary>
        /// Method to update an item in Cacheable List
        /// </summary>
        /// <param name="predicate">Predicate To Find Item To Update</param>
        /// <param name="newValue">New Value Of Item To Update</param>
        /// <param name="changeOnDb">true if you want to update it in Database</param>
        public void Update(Func<T, bool> predicate, T newValue, bool changeOnDb)
        {
            if (null != OnUpdate)
            {
                OnUpdate(this, newValue, changeOnDb);
            }
            T item = this.FirstOrDefault(predicate);
            if (item != null)
            {
                base.Remove(item);
            }
            base.Add(newValue);
        }
    }
}
